#-*- coding:utf-8 -*-
import os
import cv2
import imageio
from moviepy.editor import *
from moviepy.audio.fx.volumex import volumex

def create_gif(image_list, gif_name, duration=0.1):
    frames = []
    for image_name in image_list:
        frames.append(imageio.imread(image_name))
    imageio.mimsave(gif_name, frames, 'GIF', duration=duration)
    return

def cut_video_to_gif(video_file_path, gif_file_path, begin_seconds, end_seconds,
                     cut_border_pixels=0, zoom_rate=0.5, frame_pickup_internal=2, frame_duration=0.1):
    video_capture = cv2.VideoCapture(video_file_path)
 
    fps = video_capture.get(cv2.CAP_PROP_FPS)
    begin_frame_index = int(begin_seconds * fps)
    end_frame_index = int(end_seconds * fps)
 
    # set read from begin_frame_index
    video_capture.set(cv2.CAP_PROP_POS_FRAMES, begin_frame_index)
 
    index = 0
    frames = []
 
    while True:
        ret, image = video_capture.read()
 
        if ret is False:
            break
 
        index += 1
        if index <= end_frame_index - begin_frame_index:
            if index % frame_pickup_internal == 0:
                cut_image = image[cut_border_pixels:(image.shape[0] - cut_border_pixels), 0:image.shape[1]]
 
                width, height = cut_image.shape[0:2]
                cut_image = cv2.resize(cut_image, (int(height * zoom_rate), int(width * zoom_rate)))
 
                image_io_img = cv2.cvtColor(cut_image, cv2.COLOR_BGR2RGB)
                frames.append(image_io_img)
        else:
            break
 
    imageio.mimsave(gif_file_path, frames, 'GIF', duration=frame_duration)

def addAudioToVideo():
    """
    为视频添加一个背景音乐
    多轨音频合成
    """
    #需添加背景音乐的视频
    video_clip = VideoFileClip(r'F:/test/video/aaa/moviepy中文手册/素材/video.mp4')
    #提取视频对应的音频，并调节音量
    video_audio_clip = video_clip.audio.volumex(0.8)
    #背景音乐
    audio_clip = AudioFileClip(r'F:/test/video/aaa/moviepy中文手册/素材/音频/察觉.mp3').volumex(0.5)
    #设置背景音乐循环，时间与视频时间一致
    audio = afx.audio_loop( audio_clip, duration=video_clip.duration)
    #视频声音和背景音乐，音频叠加
    audio_clip_add = CompositeAudioClip([video_audio_clip,audio])
    #视频写入背景音
    final_video = video_clip.set_audio(audio_clip_add)
    #将处理完成的视频保存
    final_video.write_videofile("video_result.mp4")

#from moviepy.editor import VideoFileClip
fg_video_path = "data/fg.mp4"

def from_video_get_mp3():
    video = VideoFileClip(fg_video_path)
    audio = video.audio
    name = fg_video_path.split('.', 1)[0] + ".mp3"
    audio.write_audiofile(name)
    return name

def add_mp3(video_have_zm):
    fg_video = VideoFileClip(fg_video_path)
    video = VideoFileClip(video_have_zm)
    audio = fg_video.audio
    videoclip2 = video.set_audio(audio)
    name1 = video_have_zm.split('.', 1)[0] + "_out.mp4"
    videoclip2.write_videofile(name1)

'''
给视频加文字
_video_source:源视频
###_video_target:要生成的视频
_text:要添加的文本
_text_duration:文本持续的时间
_text_font_size=70:字体大小
_text_color='white':字体颜色
_text_pos='center':字体位置
'''
def add_mask_text_on_video(_video_source,_text,_text_duration=None,_text_font_size=70,_text_color='white',_text_pos='center'):
    # 从本地载入视频myHolidays.mp4并截取00:00:50 - 00:00:60部分
    #clip = VideoFileClip(_video).subclip(0,15)
    clip = VideoFileClip(_video_source)
    # 调低音频音量 (volume x 0.8)
    #clip = clip.volumex(0.8)
    # 做一个txt clip. 自定义样式，颜色.
    txt_clip = TextClip(_text,font='simsun.ttc',fontsize=_text_font_size,color=_text_color)
    # 文本clip在屏幕正中显示持续_text_duration秒
    if _text_duration is None:
        _text_duration = clip.duration
    txt_clip = txt_clip.set_pos(_text_pos).set_duration(_text_duration)
    # 把 text clip 的内容覆盖 video clip
    #video = CompositeVideoClip([clip, txt_clip])
    # 把最后生成的视频导出到文件内
    #video.write_videofile(_video_target)
    return CompositeVideoClip([clip, txt_clip])

'''
从视频中提取gif
_video:原视频
_start_second:起始秒
_end_second:结束秒
_target_gif_file:gif文件保存地址文件名
_zoom_rate:放大倍数 0<_zoom_rate<1即为缩小
'''
def get_gif_from_video(_video,_start_second,_end_second,_target_gif_file,_zoom_rate=0.5):
    video = VideoFileClip(_video).subclip(_start_second,_end_second)#.resize(_zoom_rate)
    video.write_gif(_target_gif_file)

'''
给视频添加音频
_audio_file:要添加的音频文件
_video_file:要添加音频的视频文件
_new_file:最终生成的文件
'''
def add_audio_on_video(_audio_file,_video_file,_new_file):
    bk_video = VideoFileClip(_video_file)
    audio_clip = AudioFileClip(_audio_file)#.subclip(0,bk_video.duration)
    audio_clip_loop = afx.audio_loop(audio_clip,duration=bk_video.duration)
    #audio_clip_add = CompositeAudioClip([bk_video.audio,audio_clip_loop])
    final_file = bk_video.set_audio(audio_clip_loop)
    final_file.write_videofile(_new_file,threads=8)

'''
调整媒体文件播放速度
_media:媒体文件
_speed_multiple:速率倍数
'''
def modify_media_speed_for_file(_media,_speed_multiple):
    m = VideoFileClip(_media)
    new_m = m.fl_time(lambda t:_speed_multiple*t,apply_to=['mask','audio','video'])
    return new_m.set_duration(m.duration/_speed_multiple)

'''
调整媒体播放速度
_media:媒体对象（VideoFileClip{_file}）
_speed_multiple:速率倍数
'''
def modify_media_speed_for_obj(_media,_speed_multiple):
    new_m = _media.fl_time(lambda t:_speed_multiple*t,apply_to=['mask','audio'])
    return new_m.set_duration(_media.duration/_speed_multiple)
import numpy as np
def modify_media_speed_Math(_media):
    new_m = _media.fl_time(lambda t:t*t,apply_to=['mask','audio'])
    return new_m.set_duration(_media.duration)
'''
倒放效果
_media:媒体对象（VideoFileClip{_file}）
'''
def modify_media_reverse_for_obj(_media):
    _duration = _media.duration-0.5
    newclip = _media.fl_time(lambda t:_duration-t,apply_to=['mask','audio','video'])
    #newclip = _media.fl(reverseFl,apply_to=['mask','audio'])
    return newclip.set_duration(_duration)
def reverseFl(gt,t):
    frame = gt(t)
    frame_region = frame[:,:,[0,2,1]]
    return frame_region

'''
保存视频 加入threads=n参数
'''
def runSaveVideo(_video,_path_file_name):
    _video.write_videofile(_path_file_name,threads=8)

'''
保存音频 write_audiofile无threads=n参数
'''
def runSaveAudio(_audio,_path_file_name):
    _audio.write_audiofile(_path_file_name)

'''
# Import everything needed to edit video clips 
from moviepy.editor import *
    
# loading video dsa gfg intro video 
clip = VideoFileClip("dsa_geek.mp4") 
     
# getting only first 5 seconds 
clip = clip.subclip(0, 15) 
  
# cutting out some part from the clip
clip = clip.cutout(3, 10)
  
# showing  clip 
clip.ipython_display(width = 360)
'''

'''
连接两个视频 之间加入渐入渐出效果
'''
def concateTowVideosAddFade(_video_file1,_video_file2,_fade_time,_to_file):
    clip1 = VideoFileClip(_video_file1)
    clip1_sub1 = clip1.subclip(0,clip1.duration-_fade_time)
    #clip1_sub2 = clip1.subclip(clip1.duration-_fade_time).fadeout(_fade_time,[1,1,1])
    clip2 = VideoFileClip(_video_file2)
    #clip2_sub1 = clip2.subclip(0,_fade_time).fadein(_fade_time,[1,1,1])
    #前段拼接到后段末尾并添加过渡特效
    #clip2在clip1.duration-1开始播放，过渡时间_fade_times
    clip2_sub1 = clip2.set_start(clip1_sub1.duration-_fade_time).crossfadein(_fade_time)
    clip2_sub2 = clip2.subclip(_fade_time)
    runSaveVideo(concatenate_videoclips([clip1_sub1,clip2_sub1,clip2_sub2]),_to_file)  # 视频合并

'''
连接多个（>=2）视频 无任何效果
'''
def concateVideos(*_video,_to_file):
    runSaveVideo(concatenate_videoclips(*_video),_to_file)

'''
连接多个（>=2）音频 无任何效果
'''
def concateAudios(_to_file,*_audio):
    runSaveAudio(concatenate_audioclips(*_audio),_to_file)

def modifyVideoVolume(_video,_config_num,_to_file):
    runSaveVideo(VideoFileClip(_video).fx(afx.volumex,_config_num),_to_file)

def modifyAudioVolume(_audio,_config_num,_to_file):
    runSaveAudio(AudioFileClip(_audio).fx(afx.volumex,_config_num),_to_file)

def getPicList(dirPath):
    picList = []
    for p in os.listdir(dirPath):
        full_p = os.path.join(dirPath,p)
        if os.path.isfile(full_p):
            picList.append(full_p)
    return picList


'''
默认按图片list倒序生成gif
若要按正序，调用函数时加入参数 sequence='' 即可
'''
def processCreateGifDesc(imgDir:str,newGifName,sequence='desc'):
    pList = getPicList(imgDir)
    _index = len(pList)-1
    _p = []
    #倒序
    if sequence == 'desc' :
        while _index >=0 :
            _p.append(pList[_index])
            _index -= 1
    else :
        for _img in pList:
            _p.append(_img)
    create_gif(_p,os.path.join(imgDir,newGifName),duration=0.1)

def getMediaListFromDir(_dir):
    mediaList = []
    files = os.listdir(_dir)
    for _f in files:
        file_path = os.path.join(_dir,_f)
        if os.path.isfile(file_path):
            #print(file_path)
            mediaList.append(file_path)
    return mediaList

def packAudioClipseToList(_dir):
    audioList = getMediaListFromDir(_dir)
    audioClipList = []
    for ac in audioList:
        audioClipList.append(AudioFileClip(ac))
    return audioClipList

VIDEO_DIR = 'C:/E/temp/pic/'
IMAGE_DIR = 'C:/E/temp/pic/'
AUDIO_DIR = 'C:/E/temp/pic/'
if __name__ == '__main__':
    #cut_video_to_gif('./jihanzhicheng.mp4', './konadara_nero.gif', 180, 180+15,cut_border_pixels=100)
    #add_mask_text_on_video(VIDEO_DIR+'1.mp4','gy 查尔斯塞隆\nhello').write_videofile(VIDEO_DIR+'maskjhzc.mp4',threads=8)
    #get_gif_from_video('C:/E/temp/pic/tara.mp4',4,9,'C:/E/temp/pic/tara1.gif')
    #temp = VideoFileClip('./aa.mkv')#.subclip(00:00)#.rotate(90).resize((1280,720))
    #temp = VideoFileClip('./gongjibu.flv').rotate(90).resize((1334,750))
    #runSaveVideo(temp,'./gongjibu.mp4')
    #concateTowVideosAddFade('./fadetext.mp4','./fadetext.mp4',3,'./jjjjjj.mp4')
    #processCreateGifDesc(IMAGE_DIR,'new.gif',sequence='')#
    #runSaveVideo(temp,'./[ Lingerie Studio Episode15 ] Etam Paris Lingerie show highlights.mp4')
    #video = VideoFileClip('qs.mp4')
    #video.write_gif('qs.gif')
    #for i in range(1,10):
    #    index = '0'+str(i)
    #    audio_temp = AudioFileClip('./audio/%s.mp3' % index)
    #    duration_time = audio_temp.duration
    #    runSaveAudio(audio_temp.subclip(90,duration_time-170),'./cutaudio/光荣时代-%s.mp3' % index)
    #video = VideoFileClip('C:/E/temp/video/NORM0002.mp4').subclip(6)
    #runSaveVideo(video,'C:/E/temp/video/final_file.mp4')
    #concateAudios(AUDIO_DIR+'bgm.mp3',packAudioClipseToList(AUDIO_DIR))
    add_audio_on_video(AUDIO_DIR+r'videoplayback.m4a',VIDEO_DIR+r'videoplayback.mp4',VIDEO_DIR+r'final.mp4')